local function has_words_before()
  local line, col = unpack(vim.api.nvim_win_get_cursor(0))
  return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil
end
local source_names = {
  nvim_lsp = "(LSP)",
  emoji = "(Emoji)",
  path = "(Path)",
  calc = "(Calc)",
  cmp_tabnine = "(Tabnine)",
  vsnip = "(Snippet)",
  luasnip = "(Snippet)",
  buffer = "(Buffer)",
  -- nvim_lsp_signature_help = "(Signature)",
  tmux = "(TMUX)",
  copilot = "(Copilot)",
  treesitter = "(TreeSitter)",
  vim_dadbod_completion = "(DADBOD)",
}

return {
  "hrsh7th/nvim-cmp",
  dependencies = {
    -- "hrsh7th/cmp-calc",
    -- "hrsh7th/cmp-emoji",
    -- "hrsh7th/cmp-cmdline",
    -- "hrsh7th/cmp-nvim-lsp-signature-help",
    -- "jc-doyle/cmp-pandoc-references",
    -- "kdheepak/cmp-latex-symbols",
  },
  opts = function(_, opts)
    local cmp = require "cmp"
    local lspkind = require "lspkind"

    return require("astronvim.utils").extend_tbl(opts, {
      completion = {
        -- 自动选中第一条
        completeopt = "menu,menuone,noinsert",
      },
      sources = cmp.config.sources {
        { name = "nvim_lsp", priority = 1000 },
        { name = "luasnip", priority = 900 },
        { name = "path", priority = 750 },
        { name = "pandoc_references", priority = 725 },
        { name = "latex_symbols", priority = 700 },
        { name = "emoji", priority = 700 },
        { name = "calc", priority = 650 },
        { name = "buffer", priority = 250 },
        -- { name = 'nvim_lsp_signature_help', priority = 250 },
      },
      mapping = {
        -- ["<CR>"] = cmp.config.disable,
        -- ctrl + e关闭补全窗口
        -- ["<C-p>"] = cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Select },
        -- ["<C-n>"] = cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Select },
        -- ["<C-k>"] = cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Select },
        -- ["<C-j>"] = cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Select },
        ["<Tab>"] = cmp.mapping(function(fallback)
          -- idea输入方式
          if cmp.visible() then
            local entry = cmp.get_selected_entry()
            if not entry then
              cmp.select_next_item { behavior = cmp.SelectBehavior.Select }
            else
              if has_words_before() then
                cmp.confirm {
                  behavior = cmp.ConfirmBehavior.Replace,
                  select = false,
                }
              else
                cmp.confirm {
                  behavior = cmp.ConfirmBehavior.Insert,
                  select = false,
                }
              end
            end
          else
            fallback()
          end
        end, { "i", "s" }),
        ["<S-Tab>"] = cmp.config.disable,
      },

      formatting = {
        format = lspkind.cmp_format {
          with_text = true, -- do not show text alongside icons
          -- mode = "symbol",
          -- maxwidth = 50, -- prevent the popup from showing more than provided characters (e.g 50 will not show more than 50 characters)
          -- symbol_map = {
          --   Array = " ",
          --   Boolean = " ",
          --   Class = " ",
          --   Color = " ",
          --   Constant = " ",
          --   Constructor = " ",
          --   Enum = " ",
          --   EnumMember = " ",
          --   Event = " ",
          --   Field = " ",
          --   File = " ",
          --   Folder = " ",
          --   Function = " ",
          --   Interface = " ",
          --   Key = " ",
          --   Keyword = " ",
          --   Method = " ",
          --   Module = " ",
          --   Namespace = " ",
          --   Null = " ",
          --   Number = " ",
          --   Object = " ",
          --   Operator = " ",
          --   Package = " ",
          --   Property = " ",
          --   Reference = "  ",
          --   Snippet = " ",
          --   String = " ",
          --   Struct = " ",
          --   Text = " ",
          --   TypeParameter = " ",
          --   Unit = " ",
          --   Value = " ",
          --   Variable = " ",
          -- },
          before = function(entry, vim_item)
            -- Source 显示提示来源
            -- vim_item.menu = "[" .. string.upper(entry.source.name) .. "]"
            vim_item.menu = source_names[entry.source.name]
            return vim_item
          end,
        },
      },
    })
  end,
}
